package cn.tedu.st.base.handler;

import cn.tedu.st.base.result.JsonResult;
import cn.tedu.st.base.exception.CustomerAuthenticationException;
import cn.tedu.st.base.result.ResultCode;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.*;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * 用户校验失败的处理器
 */
@Component
@Slf4j
public class LoginFailureHandler implements AuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        log.debug("进入LoginFailureHandler-----------");
        // 设置响应内容类型为 JSON，并指定字符编码为 UTF-8
        response.setContentType("application/json;charset=utf-8");

        // 获取响应的输出流，用于写入 JSON 数据
        ServletOutputStream outputStream = response.getOutputStream();

        log.debug("表单校验失败异常exception={}:",exception.getMessage(),exception);
        String jsonString = "";

        if (exception instanceof AccountExpiredException) {
            //账户过期异常    无权访问,请联系管理员
            jsonString = JSON.toJSONString(JsonResult.failure(ResultCode.ACCOUNT_EXPIRED), SerializerFeature.DisableCircularReferenceDetect);
        }
        else if (exception instanceof BadCredentialsException) {
            //用户名或密码错误异常        用户名和密码错误
            jsonString = JSON.toJSONString(JsonResult.failure(ResultCode.USERNAME_PASSWORD_ERROR), SerializerFeature.DisableCircularReferenceDetect);
        }
        else if (exception instanceof CredentialsExpiredException) {
            //密码过期异常   密码过期
            jsonString = JSON.toJSONString(JsonResult.failure(ResultCode.USERNAME_PASSWORD_EXPIRED), SerializerFeature.DisableCircularReferenceDetect);
        }
        else if (exception instanceof DisabledException) {
            //账户禁用异常    账户被禁用,登录失败
            jsonString = JSON.toJSONString(JsonResult.failure(ResultCode.ACCOUNT_DISABLED), SerializerFeature.DisableCircularReferenceDetect);
        }
        else if (exception instanceof LockedException) {
            //账户被锁定      账户被锁定,登录失败
            jsonString = JSON.toJSONString(JsonResult.failure(ResultCode.ACCOUNT_LOCKED), SerializerFeature.DisableCircularReferenceDetect);
        }
        else if (exception instanceof InternalAuthenticationServiceException) {
            //通常与系统内部的配置、数据访问或依赖服务故障相关，而非用户提供的凭证（如用户名、密码）问题。
            jsonString = JSON.toJSONString(JsonResult.failure(ResultCode.SERVER_ERROR), SerializerFeature.DisableCircularReferenceDetect);
        }
        else if (exception instanceof UsernameNotFoundException) {
            //用户不存在异常   用户名不存在
            jsonString = JSON.toJSONString(JsonResult.failure(ResultCode.USERNAME_NOT_EXIST), SerializerFeature.DisableCircularReferenceDetect);
        }
        else if (exception instanceof AuthenticationServiceException) {
            //认证服务内部错误（如数据库连接失败、第三方认证服务不可用）   系统繁忙, 请稍后再试
            jsonString = JSON.toJSONString(JsonResult.failure(ResultCode.SERVER_BUSY), SerializerFeature.DisableCircularReferenceDetect);
        }
        else if (exception instanceof InsufficientAuthenticationException) {
            //请求未携带足够的认证信息（如未提供 Token）
            jsonString = JSON.toJSONString(JsonResult.failure(ResultCode.TOKEN_IS_NULL), SerializerFeature.DisableCircularReferenceDetect);
        }
        else if (exception instanceof CustomerAuthenticationException) {
            //自定义异常
            jsonString = JSON.toJSONString(JsonResult.custom(600, exception.getMessage()), SerializerFeature.DisableCircularReferenceDetect);
        }
        else {
            //登录失败异常   兜底     登陆失败
            jsonString = JSON.toJSONString(JsonResult.failure(ResultCode.LOGIN_FAILURE), SerializerFeature.DisableCircularReferenceDetect);
        }


        // 将 JSON 字符串写入响应的输出流，并指定字符编码为 UTF-8
        outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
        outputStream.flush();
        outputStream.close();
        log.debug("LoginFailureHandler结束-----------");
    }
}
